"""
邮箱服务模块
用于发送验证码邮件
"""
import smtplib
import random
import string
from datetime import datetime, timedelta
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from typing import Optional, Dict
from pathlib import Path

# 尝试导入邮箱配置
try:
    import sys
    import importlib.util
    config_path = Path(__file__).parent.parent / "config" / "email_config.py"
    if config_path.exists():
        spec = importlib.util.spec_from_file_location("email_config", config_path)
        email_config = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(email_config)
        EMAIL_HOST = email_config.EMAIL_HOST
        EMAIL_PORT = email_config.EMAIL_PORT
        EMAIL_USER = email_config.EMAIL_USER
        EMAIL_PASSWORD = email_config.EMAIL_PASSWORD
        EMAIL_FROM_NAME = email_config.EMAIL_FROM_NAME
        VERIFY_CODE_EXPIRE_MINUTES = email_config.VERIFY_CODE_EXPIRE_MINUTES
    else:
        # 如果配置文件不存在，使用默认值（需要用户配置）
        EMAIL_HOST = "smtp.qq.com"
        EMAIL_PORT = 587
        EMAIL_USER = ""
        EMAIL_PASSWORD = ""
        EMAIL_FROM_NAME = "信息工程学展示平台"
        VERIFY_CODE_EXPIRE_MINUTES = 10
except Exception as e:
    print(f"加载邮箱配置失败: {e}")
    EMAIL_HOST = "smtp.qq.com"
    EMAIL_PORT = 587
    EMAIL_USER = ""
    EMAIL_PASSWORD = ""
    EMAIL_FROM_NAME = "信息工程学展示平台"
    VERIFY_CODE_EXPIRE_MINUTES = 10

# 存储验证码（实际项目中应使用Redis等）
VERIFY_CODES: Dict[str, Dict[str, any]] = {}


def generate_verify_code(length: int = 6) -> str:
    """生成数字验证码"""
    return "".join(random.choices(string.digits, k=length))


def save_verify_code(email: str, code: str) -> None:
    """保存验证码及过期时间"""
    expire_time = datetime.now() + timedelta(minutes=VERIFY_CODE_EXPIRE_MINUTES)
    VERIFY_CODES[email] = {
        "code": code,
        "expire_time": expire_time.isoformat(),
    }


def verify_code(email: str, code: str) -> bool:
    """验证验证码"""
    if email not in VERIFY_CODES:
        return False
    
    verify_data = VERIFY_CODES[email]
    expire_time = datetime.fromisoformat(verify_data["expire_time"])
    
    if datetime.now() > expire_time:
        # 验证码已过期，删除
        del VERIFY_CODES[email]
        return False
    
    if verify_data["code"] != code:
        return False
    
    # 验证成功，删除验证码
    del VERIFY_CODES[email]
    return True


def send_verify_email(to_email: str, code: str) -> bool:
    """
    发送验证码邮件
    
    Args:
        to_email: 收件人邮箱
        code: 验证码
    
    Returns:
        bool: 发送是否成功
    """
    if not EMAIL_USER or not EMAIL_PASSWORD:
        print("警告: 邮箱配置未设置，无法发送邮件")
        print("请复制 config/email_config.py.example 为 config/email_config.py 并填写配置")
        return False
    
    try:
        # 创建邮件
        msg = MIMEMultipart()
        msg["From"] = f"{EMAIL_FROM_NAME} <{EMAIL_USER}>"
        msg["To"] = to_email
        msg["Subject"] = "【信息工程学展示平台】邮箱验证码"
        
        # 邮件正文
        html_content = f"""
        <html>
        <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
            <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                <h2 style="color: #409eff;">邮箱验证码</h2>
                <p>您好，</p>
                <p>您正在注册信息工程学展示平台，验证码为：</p>
                <div style="background: #f0f9ff; border-left: 4px solid #409eff; padding: 15px; margin: 20px 0; font-size: 24px; font-weight: bold; color: #409eff; text-align: center;">
                    {code}
                </div>
                <p>验证码有效期为 {VERIFY_CODE_EXPIRE_MINUTES} 分钟，请勿泄露给他人。</p>
                <p>如果这不是您的操作，请忽略此邮件。</p>
                <hr style="border: none; border-top: 1px solid #eee; margin: 20px 0;">
                <p style="color: #999; font-size: 12px;">此邮件由系统自动发送，请勿回复。</p>
            </div>
        </body>
        </html>
        """
        
        msg.attach(MIMEText(html_content, "html", "utf-8"))
        
        # 发送邮件
        with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server:
            server.starttls()  # 启用TLS加密
            server.login(EMAIL_USER, EMAIL_PASSWORD)
            server.send_message(msg)
        
        return True
    except Exception as e:
        print(f"发送邮件失败: {e}")
        return False


def send_verify_code(email: str) -> Optional[str]:
    """
    生成并发送验证码
    
    Args:
        email: 收件人邮箱
    
    Returns:
        Optional[str]: 验证码（如果发送成功），None（如果发送失败）
    """
    code = generate_verify_code()
    save_verify_code(email, code)
    
    if send_verify_email(email, code):
        return code
    return None

